﻿// ***********************************************************************
// Assembly         : CommonLayer
// Author           : LJO+01 (Laurent Jordi)
// Created          : 06-05-2013
//
// Last Modified By : LJO+01 (Laurent Jordi)
// Last Modified On : 06-06-2013
// ***********************************************************************
// <copyright file="LayoutViewControllersStaticTools.cs" company="Copyright © Innovacall 2011">
//     Copyright (c) Copyright © Innovacall 2011. All rights reserved.
// </copyright>
// <summary></summary>
// ***********************************************************************
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Xml.Linq;
using InnovaApp.Layers.DataLayer;
using InnovaApp.Layers.DomainLayer;
using InnovaApp.Layers.ResourcesLayer.Properties;
using INNOVACALL.Framework.Common.Models.ViewModels.MetaModels;
using INNOVACALL.Framework.Common.Models.ViewModels.MetaModels.LayoutMenus;

namespace InnovaApp.Layers.CommonLayer.Controllers.ViewControllers.LayoutViewControllers
{
    /// <summary>
    /// Class LayoutViewControllersStaticTools
    /// </summary>
    public class LayoutViewControllersStaticTools
    {
        /// <summary>
        /// The e method base
        /// </summary>
        private static string eMethodBase = "ControllerBaseStaticTools";
        /// <summary>
        /// Feeds the menus.
        /// </summary>
        /// <param name="menus">The menus.</param>
        /// <param name="_dataContext">The _data context.</param>
        /// <param name="dbLanguage">The db language.</param>
        /// <param name="defaultLanguage">The default language.</param>
        /// <param name="adminMode">if set to <c>true</c> [admin mode].</param>
        /// <param name="currentUser">The current user.</param>
        /// <exception cref="INNOVACALL.Framework.Common.InnovacallExceptions.DataIntegrityException"></exception>
        public static void FeedMenus(LayoutMenuElements_MetaModel menus, DataRepositories _dataContext, Language dbLanguage, string defaultLanguage, bool adminMode, MembershipUser currentUser)
        {
            bool dbMenuIsActive;
            string eMethod = eMethodBase + "FeedMenus";
            object eParameters = new { menus = menus, _dataContext = _dataContext, language = dbLanguage.Description, defaultLanguage = defaultLanguage, adminMode = adminMode };
            List<LayoutMenu> dbMenus = _dataContext.LayoutMenu_Rep.Query(x => !x.FK_LayoutMenu.HasValue).OrderBy(x => x.SortIndex).ToList();

            foreach (LayoutMenu dbMenu in dbMenus)
            {
                LayoutMenu_Translation dbLayoutMenu_Translation = _dataContext.LayoutMenu_Translation_Rep.Query(x => x.FK_LayoutMenu == dbMenu.Id && x.FK_Language == dbLanguage.Id).FirstOrDefault();
                if (dbLayoutMenu_Translation == null)
                {
                    throw new INNOVACALL.Framework.Common.InnovacallExceptions.DataIntegrityException(eMethod, eParameters, Resources.ControllerBaseStaticTools_Err_LayoutMenu_Translation);
                }
                dbMenuIsActive = dbLayoutMenu_Translation.Active;
                LayoutMenu_Translation_MetaModel menuElementToAdd = null;
                int SubLevelMenuCount = dbMenus.Count;
                if (!adminMode && dbMenuIsActive)
                {
                    if (MenuCanBeAdded(dbLayoutMenu_Translation, currentUser))
                    {
                        menuElementToAdd = FeedMenu(_dataContext, dbLayoutMenu_Translation, dbLanguage, defaultLanguage, adminMode, SubLevelMenuCount, currentUser);
                        menuElementToAdd.CssClass = "MenuBarItem";
                        menus.Add(menuElementToAdd);
                    }
                }
                else if (adminMode)
                {
                    menuElementToAdd = FeedMenu(_dataContext, dbLayoutMenu_Translation, dbLanguage, defaultLanguage, adminMode, SubLevelMenuCount, currentUser); ;
                    menuElementToAdd.CssClass = "MenuBarItem";
                    menus.Add(menuElementToAdd);
                }
            }
            if (adminMode)
            {
                //This is a virtual Menu for the last item of the MenuBar to create new Menu
                LayoutMenu_Translation_MetaModel menuElementToAdd = new LayoutMenu_Translation_MetaModel()
                {
                    Language = new Language_MetaModel(dbLanguage.Description),
                    AdminMode = true,
                    CssClass = "MenuBarItem",
                    Id = -1,
                    LayoutMenuTranslationLayoutMenuParent = null,
                    Controller = "DynaStructureController",
                    DefaultAction = "LayoutMenuItemFeed",
                    ButtonCaption = "",
                    SortIndex = dbMenus.Count + 1,
                    LevelCount = dbMenus.Count,
                    ButtonToolTip = Resources.DynaStructure_AddMenuFirstLevel
                };
                menus.Add(menuElementToAdd);
            }
        }

        /// <summary>
        /// Feeds the menu.
        /// </summary>
        /// <param name="_dataContext">The _data context.</param>
        /// <param name="dbLayoutMenu_Translation">The db layout menu_ translation.</param>
        /// <param name="dbLanguage">The db language.</param>
        /// <param name="defaultLanguage">The default language.</param>
        /// <param name="adminMode">if set to <c>true</c> [admin mode].</param>
        /// <param name="levelCount">The level count.</param>
        /// <param name="currentUser">The current user.</param>
        /// <returns>LayoutMenu_Translation_MetaModel.</returns>
        /// <exception cref="INNOVACALL.Framework.Common.InnovacallExceptions.DataIntegrityException">
        /// </exception>
        protected static LayoutMenu_Translation_MetaModel FeedMenu(DataRepositories _dataContext, LayoutMenu_Translation dbLayoutMenu_Translation, Language dbLanguage, string defaultLanguage, bool adminMode, int levelCount, MembershipUser currentUser)
        {
            string eMethod = eMethodBase + ".LayoutMenuElement_MetaModel";
            object eParameters = new { _dataContext = _dataContext, dbLayoutMenu_Translation = dbLayoutMenu_Translation, language = dbLanguage.Description, defaultLanguage = defaultLanguage, adminMode = adminMode, levelCount = levelCount };
            LayoutMenu_Translation_MetaModel toReturn = new LayoutMenu_Translation_MetaModel();
            Structure_Page attachedPage = dbLayoutMenu_Translation.Structure_Page.OrderBy(x => x.SortIndex).First();
            string ancestors = string.Empty;
            BuildAncestorsString(dbLayoutMenu_Translation, ref ancestors);//, dbLanguage);
            toReturn.Id = dbLayoutMenu_Translation.Id;
            toReturn.FK_LayoutMenu = dbLayoutMenu_Translation.FK_LayoutMenu;
            toReturn.Active = dbLayoutMenu_Translation.Active;
            toReturn.AdminMode = adminMode;
            toReturn.Ancestors = ancestors;
            toReturn.Controller = dbLayoutMenu_Translation.LayoutMenu.Controller;
            toReturn.CssClass = dbLayoutMenu_Translation.CssClass;
            toReturn.DefaultAction = dbLayoutMenu_Translation.LayoutMenu.DefaultAction;
            toReturn.LayoutMenuTranslationLayoutMenuParent = dbLayoutMenu_Translation.LayoutMenu.FK_LayoutMenu;
            toReturn.Language = new Language_MetaModel(dbLanguage.Description);
            toReturn.LanguageIndex = -1;
            toReturn.LevelCount = levelCount;
            toReturn.MenuNameURLFormatted = dbLayoutMenu_Translation.MenuNameURLFormatted;
            toReturn.OriginalDirectURL = toReturn.DirectURL;
            toReturn.PageNameURLFormatted = attachedPage.PageNameURLFormatted;
            toReturn.ButtonCaption = dbLayoutMenu_Translation.ButtonCaption;
            toReturn.ButtonToolTip = dbLayoutMenu_Translation.ButtonToolTip;
            toReturn.SortIndex = dbLayoutMenu_Translation.LayoutMenu.SortIndex;

            toReturn.DirectURL = attachedPage.DirectURL;
            toReturn.PageTitle = attachedPage.Title;

            toReturn.SubMenus = new LayoutMenuElements_MetaModel();

            Structure_Page dbStructure_Page;
            bool dbMenuIsActive;
            if (dbLayoutMenu_Translation.LayoutMenu.Id == 1 && dbLanguage.Description == defaultLanguage)
            {
                toReturn.DirectURL = "/";
                dbStructure_Page = _dataContext.Structure_Page_Rep.Query(x => x.FK_LayoutMenu_Translation == dbLayoutMenu_Translation.Id && x.DirectURL == "/").SingleOrDefault();
                if (dbStructure_Page == null)
                {
                    throw new INNOVACALL.Framework.Common.InnovacallExceptions.DataIntegrityException(eMethod, eParameters, string.Format(Resources.ControllerBaseStaticTools_FeedMenu_Err_dbStructure_Page_null, "/"));
                }
                toReturn.ButtonCaption = dbLayoutMenu_Translation.ButtonCaption;
                toReturn.ButtonToolTip = dbLayoutMenu_Translation.ButtonToolTip;
            }
            else
            {
                dbStructure_Page = dbLayoutMenu_Translation.Structure_Page.Where(x => x.FK_LayoutMenu_Translation == dbLayoutMenu_Translation.Id && x.DirectURL.StartsWith("/" + dbLanguage.Description)).FirstOrDefault();
                if (dbStructure_Page == null)
                {
                    throw new INNOVACALL.Framework.Common.InnovacallExceptions.DataIntegrityException(eMethod, eParameters, string.Format(Resources.ControllerBaseStaticTools_FeedMenu_Err_dbStructure_Page_null, "/" + dbLanguage.Description));
                }
                else
                {
                    toReturn.DirectURL = dbStructure_Page.DirectURL;
                    toReturn.ButtonCaption = dbLayoutMenu_Translation.ButtonCaption;
                    toReturn.ButtonToolTip = dbLayoutMenu_Translation.ButtonToolTip;
                }
            }
            if (dbLayoutMenu_Translation.LayoutMenu.LayoutMenu1.Count > 0)
            {
                foreach (LayoutMenu subMenu in dbLayoutMenu_Translation.LayoutMenu.LayoutMenu1.OrderBy(x => x.SortIndex))
                {
                    dbLayoutMenu_Translation = subMenu.LayoutMenu_Translation.Where(x => x.FK_LayoutMenu == subMenu.Id && x.FK_Language == dbLanguage.Id).FirstOrDefault();
                    if (dbLayoutMenu_Translation == null)
                    {
                        throw new INNOVACALL.Framework.Common.InnovacallExceptions.DataIntegrityException(eMethod, eParameters, string.Format(Resources.ControllerBaseStaticTools_FeedMenu_Err_dbLayoutMenu_Translation_null, subMenu.Id, dbLanguage.Description));
                    }
                    dbMenuIsActive = dbLayoutMenu_Translation.Active;
                    int SubLevelMenuCount = subMenu.LayoutMenu2.LayoutMenu1.Count;
                    if (!adminMode && dbMenuIsActive)
                    {
                        if (MenuCanBeAdded(dbLayoutMenu_Translation, currentUser))
                        {
                            toReturn.SubMenus.Add(FeedMenu(_dataContext, dbLayoutMenu_Translation, dbLanguage, defaultLanguage, adminMode, SubLevelMenuCount, currentUser));
                        }
                    }
                    else if (adminMode)
                    {
                        toReturn.SubMenus.Add(FeedMenu(_dataContext, dbLayoutMenu_Translation, dbLanguage, defaultLanguage, adminMode, SubLevelMenuCount, currentUser));
                    }
                }
            }
            toReturn.CssClass = "MenuElementItem";
            return toReturn;
        }

        /// <summary>
        /// Builds the ancestors string.
        /// </summary>
        /// <param name="dbLayoutMenu_Translation">The db layout menu_ translation.</param>
        /// <param name="ancestors">The ancestors.</param>
        public static void BuildAncestorsString(LayoutMenu_Translation dbLayoutMenu_Translation, ref string ancestors)//, Language dbLanguage)
        {
            Language dbLanguage = dbLayoutMenu_Translation.Language;
            if (dbLayoutMenu_Translation.LayoutMenu.LayoutMenu2 != null)
            {
                LayoutMenu_Translation parent = dbLayoutMenu_Translation.LayoutMenu.LayoutMenu2.LayoutMenu_Translation.Where(x => x.FK_Language == dbLanguage.Id).Single();
                BuildAncestorsString(parent, ref ancestors);
                if (!string.IsNullOrEmpty(ancestors))
                {
                    ancestors = ancestors + "/";
                }
                ancestors = ancestors + parent.MenuNameURLFormatted;
            }
        }

        /// <summary>
        /// Builds the ancestors string.
        /// </summary>
        /// <param name="dbLanguage">The db language.</param>
        /// <param name="dbParentLayoutMenu">The db parent layout menu.</param>
        /// <param name="ancestors">The ancestors.</param>
        public static void BuildAncestorsString(Language dbLanguage, LayoutMenu dbParentLayoutMenu, ref string ancestors)
        {
            if (dbParentLayoutMenu != null)
            {
                LayoutMenu_Translation parent = dbParentLayoutMenu.LayoutMenu_Translation.Where(x => x.FK_Language == dbLanguage.Id).Single();
                BuildAncestorsString(dbLanguage, parent.LayoutMenu.LayoutMenu2, ref ancestors);
                if (!string.IsNullOrEmpty(ancestors))
                {
                    ancestors = ancestors + "/";
                }
                ancestors = ancestors + parent.MenuNameURLFormatted;
            }
        }


        /// <summary>
        /// ToDo Improve GetCustomControllersList
        /// </summary>
        /// <returns>List{SelectListItem}.</returns>
        public static List<SelectListItem> GetCustomControllersList()
        {
            List<SelectListItem> toReturn = new List<SelectListItem>();
            toReturn.Add(new SelectListItem() { Value = "ContactFormPublicController", Text = Resources.CustomControllers_ContactFormPublicController });
            return toReturn;
        }
        /// <summary>
        /// Determines whether [is A home page] [the specified dblayout menu].
        /// </summary>
        /// <param name="dblayoutMenu">The dblayout menu.</param>
        /// <returns><c>true</c> if [is A home page] [the specified dblayout menu]; otherwise, <c>false</c>.</returns>
        public static bool IsAHomePage(LayoutMenu dblayoutMenu)
        {
            bool toReturn = false;
            toReturn = dblayoutMenu.FK_LayoutMenu == null && dblayoutMenu.SortIndex == 1;
            return toReturn;
        }

        /// <summary>
        /// Gets the page name URL formatted.
        /// </summary>
        /// <param name="isAHomePage">if set to <c>true</c> [is A home page].</param>
        /// <param name="dbStructure_Page">The db structure_ page.</param>
        /// <returns>System.String.</returns>
        public static string GetPageNameURLFormatted(bool isAHomePage, Structure_Page dbStructure_Page)
        {
            string toReturn = string.Empty;
            string pageNamePart = string.Empty;
            if (isAHomePage)
            {
                toReturn = string.Format("{0}", Resources.View_DyanContent_HomePageName);
            }
            else
            {
                string[] tDirectURL = dbStructure_Page.DirectURL.Split('/');
                pageNamePart = tDirectURL.Last();
                toReturn = pageNamePart.Substring(0, pageNamePart.Length - 4);
            }
            return toReturn;
        }
        /// <summary>
        /// http://www.rssboard.org/rss-2-0-1
        /// </summary>
        /// <param name="_dataContext">The _data context.</param>
        /// <returns>XDocument.</returns>
        public static XDocument RSS(DataRepositories _dataContext)
        {
            XDocument toReturn = new XDocument();
            //RSS
            XElement root = new XElement("rss", new XAttribute("version", "2.0"));
            //string[] tLangues = ConfigurationManager.AppSettings["Languages"].Split(',');
            //List<Language_MetaModel> languages = tLangues.Select(x => new Language_MetaModel(x)).ToList();
            //XElement channel = new XElement("channel");
            //XElement channelElement;
            //channelElement = new XElement("language", language.Language);
            //channel.Add(channelElement);
            //channelElement = new XElement("image", language.Flag);
            //channel.Add(channelElement);
            //channelElement = new XElement("link", string.Format(@"http://{0}/", HttpContext.Current.Request.Url.Authority));
            //channel.Add(channelElement);
            //if (!(ConfigurationManager.AppSettings["RSS_SiteTitle"] == null))
            //{
            //    channelElement = new XElement("title", ConfigurationManager.AppSettings["RSS_SiteTitle"]);
            //}
            //else
            //{
            //    channelElement = new XElement("title", string.Format("{0} (My Pretty CMS)", HttpContext.Current.Request.Url.Authority));
            //}
            //channel.Add(channelElement);
            //if (!(ConfigurationManager.AppSettings["RSS_copyright"] == null))
            //{
            //    channelElement = new XElement("copyright", ConfigurationManager.AppSettings["RSS_copyright"]);
            //    channel.Add(channelElement);
            //}
            //if (!(ConfigurationManager.AppSettings["RSS_managingEditor"] == null))
            //{
            //    channelElement = new XElement("managingEditor", ConfigurationManager.AppSettings["RSS_managingEditor"]);
            //    channel.Add(channelElement);
            //}
            //if (!(ConfigurationManager.AppSettings["RSS_webMaster"] == null))
            //{
            //    channelElement = new XElement("webMaster", ConfigurationManager.AppSettings["RSS_webMaster"]);
            //    channel.Add(channelElement);
            //}
            //if (!(ConfigurationManager.AppSettings["RSS_category"] == null))
            //{
            //    channelElement = new XElement("category", ConfigurationManager.AppSettings["RSS_category"]);
            //    channel.Add(channelElement);
            //}
            ///*ToDo pubDate see http://asg.web.cmu.edu/rfc/rfc822.html#sec-5
            //channelElement = new XElement("pubDate",pubDate);
            //channel.Add(channelElement);
            //*/
            ///*
            //ToDo lastBuildDate see http://asg.web.cmu.edu/rfc/rfc822.html#sec-5
            //channelElement = new XElement("lastBuildDate",pubDate);
            //channel.Add(channelElement);
            //*/
            //channelElement = new XElement("generator", "Inovacall MyPrettyCMS");
            //channel.Add(channelElement);
            //channelElement = new XElement("docs", "http://www.rssboard.org/rss-2-0-1");
            //channel.Add(channelElement);
            //if (!(ConfigurationManager.AppSettings["RSS_ttl"] == null))
            //{
            //    channelElement = new XElement("ttl", ConfigurationManager.AppSettings["RSS_ttl"]);
            //}
            //else
            //{
            //    channelElement = new XElement("ttl", "60");
            //}
            //channel.Add(channelElement);
            ////if(!(ConfigurationManager.AppSettings["RSS_image"] == null)){
            ////    channelElement = new XElement("image",ConfigurationManager.AppSettings["RSS_image"]);
            ////} else {
            ////    channelElement = new XElement("image","/images/rss.png");
            ////}
            //channel.Add(channelElement);
            //if (!(ConfigurationManager.AppSettings["RSS_PICS"] == null))
            //{
            //    channelElement = new XElement("rating", ConfigurationManager.AppSettings["RSS_rating"]);
            //    channel.Add(channelElement);
            //}
            //foreach (Language_MetaModel language in languages)
            //{
            //    Language dbLanguage = _dataContext.Language_Rep.Query(x => x.Description == language.Language).FirstOrDefault();
            //    List<Structure_Page> dbStructure_Pages = _dataContext.Structure_Page_Rep.Query(x => x.LayoutMenu_Translation.FK_Language == dbLanguage.Id).ToList();
            //    foreach (Structure_Page dbStructure_Page in dbStructure_Pages)
            //    {
            //        //Items
            //        FeedRSSItems(_dataContext, ref channel, dbStructure_Page);
            //        root.Add(channel);
            //    }
            //}
            toReturn.Add(root);
            return toReturn;
        }

        /// <summary>
        /// Feeds the RSS items.
        /// </summary>
        /// <param name="_dataContext">The _data context.</param>
        /// <param name="channel">The channel.</param>
        /// <param name="dbStructure_Page">The db structure_ page.</param>
        private static void FeedRSSItems(DataRepositories _dataContext, ref XElement channel, Structure_Page dbStructure_Page)
        {
            string authority = HttpContext.Current.Request.Url.Authority;
            XElement item = new XElement("item");
            XElement itemElement;
            itemElement = new XElement("title", dbStructure_Page.Title);
            item.Add(itemElement);
            itemElement = new XElement("link", "http://" + authority + dbStructure_Page.DirectURL);
            item.Add(itemElement);
            itemElement = new XElement("description", HttpContext.Current.Server.HtmlEncode(dbStructure_Page.Description));
            item.Add(itemElement);
            /* ToDo Author */
            itemElement = new XElement("category", dbStructure_Page.IndexingCategory);
            item.Add(itemElement);
            itemElement = new XElement("category", dbStructure_Page.IndexingCategory);
            item.Add(itemElement);
            /* ToDo Comments */
            /* ToDo Enclosure */
            /* ToDo guid */
            /* ToDo pupDate */
            /* ToDo source */
            channel.Add(item);
        }
        /// <summary>
        /// Menus the can be added.
        /// </summary>
        /// <param name="dbLayoutMenu_Translation">The db layout menu_ translation.</param>
        /// <param name="currentUser">The current user.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
        private static bool MenuCanBeAdded(LayoutMenu_Translation dbLayoutMenu_Translation, MembershipUser currentUser)
        {
            bool toReturn = false;
            bool privateController = dbLayoutMenu_Translation.LayoutMenu.Controller.ToLower().Contains("private");
            toReturn = !privateController;
            if (!toReturn)
            {
                if (dbLayoutMenu_Translation.LayoutMenu.DisplayMenuToPublicIfPrivate.HasValue && dbLayoutMenu_Translation.LayoutMenu.DisplayMenuToPublicIfPrivate.Value)
                {
                    toReturn = true;
                }
                else
                {
                    if (currentUser != null)
                    {
                        toReturn = true;
                    }
                }
            }
            return toReturn;
        }
        /// <summary>
        /// Obtain the list of child controllers in a namespace
        /// </summary>
        /// <param name="selectController">The select controller.</param>
        /// <returns>List{SelectListItem}.</returns>
        public static List<SelectListItem> GetMenuControllers(string selectController)         
        {
            List<SelectListItem> toReturn = new List<SelectListItem>();
            Assembly asm = System.Reflection.Assembly.GetCallingAssembly();
            List<string> controllerNames = new List<string>();
            controllerNames.AddRange(asm.GetExportedTypes().Where(x => typeof(IController).IsAssignableFrom(x) && !x.IsAbstract && x.Namespace.Contains(CommonEnvironment.DynaContentControllersBaseNamespace)).Select(x => x.Name.Substring(0, x.Name.Length - "Controller".Length)).AsEnumerable());
            controllerNames.AddRange(asm.GetExportedTypes().Where(x => typeof(IController).IsAssignableFrom(x) && !x.IsAbstract && x.Namespace.Contains(CommonEnvironment.CustomControllersBaseNamespace)).Select(x => x.Name.Substring(0, x.Name.Length - "Controller".Length)).AsEnumerable());
            controllerNames.Remove("CustomControllerTemplate");
            toReturn.Add(new SelectListItem() { Value = "", Text = Resources.View_LayoutMenu_SelectDefaultController, Selected = string.IsNullOrEmpty(selectController) });
            toReturn.AddRange(controllerNames.Select(x => new SelectListItem(){Selected = selectController == x, Text = x, Value=x}).ToList());             
            toReturn = toReturn.OrderBy(x => x.Text).ToList();             
            return toReturn;         
        }
        /// <summary>
        /// Obtain the list of actions of a controller.
        /// ToDo : improve it with reflexion
        /// </summary>
        /// <param name="selectController">The select controller.</param>
        /// <param name="selectAction">The select action.</param>
        /// <returns>List{SelectListItem}.</returns>
        public static List<SelectListItem> GetMenuControllerActions(string selectController, string selectAction)         
        {             
            List<SelectListItem> toReturn = new List<SelectListItem>();             
            toReturn.Add(new SelectListItem() { Value = "", Text = Resources.View_LayoutMenu_SelectDefaultAction, Selected = string.IsNullOrEmpty(selectAction) });
            toReturn.Add(new SelectListItem() { Value = "Index", Text = "Index", Selected = selectAction == "Index" });             
            return toReturn;         
        }
    }
}
